package com.blog.wl2023.service.com;

import cn.hutool.core.util.IdUtil;
import com.blog.wl2023.entity.*;
import com.blog.wl2023.entity.response.PageResult;
import com.blog.wl2023.entity.response.Result;
import com.blog.wl2023.repository.*;
import jakarta.persistence.criteria.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author wule
 * @desc 公共服务层
 */
@Service
public class ComService {

	@Autowired
	ArticleRepository articleRepository;
	@Autowired
	TypeRepository typeRepository;
	@Autowired
	ArticleCommentRepository articleCommentRepository;
	@Autowired
	CapriceRepository capriceRepository;
	@Autowired
	MessageListRepository messageListRepository;
	@Autowired
	TreasureChestsRepository treasureChestsRepository;
	@Autowired
	AnnouncementRepository announcementRepository;

	public Result getAbout() {
		//通过uuid == 001 找出关于的文章的信息
		Article article = articleRepository.findByUUidInAbout();
		return Result.ok(article);
	}

	public Result getType() {
		List<Type> typeList = typeRepository.findAll();
		return Result.ok(typeList);
	}

	public Result getArticle(String uuid) {
		//更新
		articleRepository.updateViews(uuid);
		//查询
		Article article = articleRepository.findByUUid(uuid);
		return Result.ok(article);
	}

	public PageResult getArticleComment(int pageNo, int pageSize, String articleUUid) {
		//查询条件存在这个对象中
		//重新Specification的toPredicate方法
		Specification<ArticleComment> specification = (root, criteriaQuery, criteriaBuilder) -> {
			//articleId相等
			Path<String> aId = root.get("articleId");
			Predicate articleIdPredicate = criteriaBuilder.equal(aId, articleUUid);
			Path<String> iD = root.get("isDelete");
			Predicate isDeletePredicate = criteriaBuilder.equal(iD, 0);
			Path<String> p = root.get("pId");
			Predicate pIdPredicate = criteriaBuilder.equal(p, "0");
			// 将用户表的字段值加入到查询结果中
			criteriaQuery.multiselect(
					root.get("uuid"),
					root.get("user").get("uuid"),
					root.get("commentContent"),
					root.get("createTime"),
					root.get("isDelete"),
					root.get("pId")
			);
			return criteriaBuilder.and(articleIdPredicate, isDeletePredicate, pIdPredicate);
		};

		//分页条件存在这个对象中
		PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "createTime"));

		//进行查询操作，第一个参数是查询条件对象，第二个参数是分页对象
		//返回的数据都封装在了Page<ArticleComment>对象中
		Page<ArticleComment> all = articleCommentRepository.findAll(specification, pageRequest);

		List<ArticleComment> content = all.getContent();
		if (content.size() > 0) {
			//进行子评论的查询
			List<ArticleComment> childComment = articleCommentRepository.findArticleChildComment(articleUUid);

			//设置评论数据的子节点
			for (ArticleComment pComment : content) {
				List<ArticleComment> comments = childComment.stream().filter(comment -> pComment.getUuid().equals(comment.getPId()))
						.peek(
								comment -> {
									User user = comment.getUser();
									comment.setImageUrl(user.getImageUrl());
									comment.setUsername(user.getUsername());
									comment.setUser(null);
								}).collect(Collectors.toList());
				pComment.setChildComment(comments);
				//设置父评论的username和imageUrl
				pComment.setUsername(pComment.getUser().getUsername());
				pComment.setImageUrl(pComment.getUser().getImageUrl());
				pComment.setUser(null);
			}
		}
		return PageResult.ok(content, all.getTotalElements(), all.getTotalPages());
	}

	public PageResult getTopArticle() {
		Specification<Article> specification = new Specification<Article>() {
			//重新Specification的toPredicate方法
			@Override
			public Predicate toPredicate(Root<Article> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				Path<String> uuid = root.get("uuid");
				Predicate uuidPredicate = criteriaBuilder.notEqual(uuid, "001");

				Path<Integer> isDelete = root.get("isDelete");
				Predicate isDeletePredicate = criteriaBuilder.equal(isDelete, 0);
				Path<Integer> isTop = root.get("isTop");
				Predicate isTopPredicate = criteriaBuilder.equal(isTop, 1);
				return criteriaBuilder.and(uuidPredicate, isDeletePredicate, isTopPredicate);
			}
		};

		//根据时间desc获取到最新置顶的三个文章属性
		PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "createTime"));

		Page<Article> articles = articleRepository.findAll(specification, pageRequest);
		return PageResult.ok(articles.getContent(), articles.getTotalElements(), articles.getTotalPages());
	}

	public Result getMessageList() {
		//获取的同时将user表关联获取,然后将imageUrl赋值之后user删除
		List<MessageList> messageList = messageListRepository.getMessageList();
		List<MessageList> messageLists = messageList.stream().peek(m -> {
			if (m.getUser()!=null){
				String imageUrl = m.getUser().getImageUrl();
				m.setImageUrl(imageUrl);
				m.setUser(null);
			}
		}).toList();
		return Result.ok(messageLists);
	}

	public PageResult getArticles(int pageNo, int pageSize, String title, String typeId) {
		Page<Article> articles = paginateFindArticle(title, typeId, pageNo, pageSize);
		return PageResult.ok(articles.getContent(), articles.getTotalElements(), articles.getTotalPages());
	}

	public Page<Article> paginateFindArticle(String titleQuery, String typeIdQuery, Integer pageNo, Integer pageSize) {
		//查询条件存在这个对象中
		Specification<Article> specification = new Specification<Article>() {
			//重新Specification的toPredicate方法
			@Override
			public Predicate toPredicate(Root<Article> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				//我要模糊查询的字段是title
				Path<String> title = root.get("title");
				//criteriaBuilder.like模糊查询，第一个参数是上一行的返回值，第二个参数是like('%xxx%')中，xxx的值
				Predicate predicate = criteriaBuilder.like(title, "%" + titleQuery + "%");

				Path<String> uuid = root.get("uuid");
				Predicate uuidPredicate = criteriaBuilder.notEqual(uuid, "001");

				Path<Integer> isDelete = root.get("isDelete");
				Predicate isDeletePredicate = criteriaBuilder.equal(isDelete, 0);

				if (!Objects.equals(typeIdQuery, "") && typeIdQuery != null) {
					Path<String> typeId = root.get("typeId");
					Predicate typeIdPredicate = criteriaBuilder.equal(typeId, typeIdQuery);
					return criteriaBuilder.and(predicate, uuidPredicate, isDeletePredicate, typeIdPredicate);
				}

				return criteriaBuilder.and(predicate, uuidPredicate, isDeletePredicate);
			}
		};
		//分页条件存在这个对象中
		PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "createTime"));

		//进行查询操作，第一个参数是查询条件对象，第二个参数是分页对象
		//返回的数据都封装在了Page<Admin>对象中
		return articleRepository.findAll(specification, pageRequest);
	}

	public PageResult getPigeonhole(int pageNo, int pageSize) {
		Page<Article> articles = paginateFindArticle("", null, pageNo, pageSize);
		return PageResult.ok(articles.getContent(), articles.getTotalElements(), articles.getTotalPages());
	}

	public PageResult getCaprice(int pageNo, int pageSize) {
		Specification<Caprice> specification = new Specification<Caprice>() {
			//重新Specification的toPredicate方法
			@Override
			public Predicate toPredicate(Root<Caprice> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				Path<Integer> isDelete = root.get("isDelete");
				Predicate isDeletePredicate = criteriaBuilder.equal(isDelete, 0);
				return criteriaBuilder.and(isDeletePredicate);
			}
		};

		//根据时间desc获取
		PageRequest pageRequest = PageRequest.of(pageNo, pageSize, Sort.by(Sort.Direction.DESC, "createTime"));
		Page<Caprice> capriceList = capriceRepository.findAll(specification, pageRequest);

		return PageResult.ok(capriceList.getContent(), capriceList.getTotalElements(), capriceList.getTotalPages());
	}

	public Result getAllTitles() {
		List<Article> articles = articleRepository.getAllTitles();
		return Result.ok(articles);
	}

	public Result postNewMessageList(MessageList messageList) {
		messageList.setUuid(IdUtil.randomUUID());
		messageList.setIsDelete(0);
		messageListRepository.save(messageList);
		return Result.ok();
	}

	public Result postNewFriendLink(TreasureChests treasureChests) {
		System.out.println(treasureChests);
		treasureChests.setUuid(IdUtil.randomUUID());
		//一开始设置为已删除,等待后台校验通过
		treasureChests.setIsDelete(1);
		treasureChestsRepository.save(treasureChests);
		return Result.ok();
	}

	public Result getTreasureChests() {
		//将所有信息获取,然后在前端拼接参数,白嫖用户算力
		List<TreasureChests> treasureChests = treasureChestsRepository.getTreasureChests();
		return Result.ok(treasureChests);
	}

	public Result getAnnouncementIsShow() {
		List<Announcement> announcements =announcementRepository.getAnnouncementIsShow();
		return Result.ok(announcements);
	}
}
